package com.coocaa.x.app.hall.upgrade;

import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.content.pm.PackageParser;
import android.net.Uri;
import android.os.Build;
import android.util.Log;

import com.alibaba.fastjson.JSONObject;
import com.coocaa.x.app.hall.R;
import com.coocaa.x.framework.app.CoocaaApplication;
import com.coocaa.x.framework.utils.Android;
import com.coocaa.x.framework.utils.FirstStart;
import com.coocaa.x.framework.utils.LiteHandlerThread;
import com.coocaa.x.framework.utils.LogUtils;
import com.coocaa.x.service.liteupgrade.LiteUpgradeKernel;
import com.coocaa.x.service.liteupgrade.aidl.UpgradeInfo;
import com.coocaa.x.service.liteupgrade.aidl.UpgradeParams;
import com.coocaa.x.uipackage.dialog.UpgradeDialog;
import com.skyworth.framework.skysdk.android.SdCardChecker;
import com.skyworth.logsdk.appstore.LogAPIForAppStore;
import com.skyworth.webSDK.webservice.tcappstore.StoreApkInfo;

import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * Created by lu on 15-6-19.
 */
public class HallUpgradeKernel extends LiteUpgradeKernel {
    private UpgradeInfo info = new UpgradeInfo();
    private String url = "";
    private UpgradeDialog upgradeDialog = null;

    private boolean can_show_dialog = false;

    private static final int SHOW_DIALOG_TYPE_ALL = 0;
    private static final int SHOW_DIALOG_TYPE_ONLY_HAS_UPDATE = 1;
    private int show_dialog_type = SHOW_DIALOG_TYPE_ALL;

    private SharedPreferences sp = null;

    public HallUpgradeKernel() {
        super();
        LogUtils.d("upgrade", "HallUpgradeKernel...");

        sp = mContext.getSharedPreferences("upgrade.kernel.hall", Context.MODE_PRIVATE);
        try {
            if (FirstStart.isFirstStart(mContext, "upgrade.kernel.hall", FirstStart.ACTION.FIRST_VERSION)) {
                FirstStart.markFirstStartFlag(mContext, "upgrade.kernel.hall");
                LogUtils.d("HallUpgradeKernel", Android.getVersionName(mContext, mContext.getPackageName()) + " is first start!!!");


                UpgradeInfo __info = null;
                try {
                    String _info = sp.getString("info", "");
                    __info = UpgradeInfo.parseJObject(_info, UpgradeInfo.class);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                if (__info != null) {
                    String _url = sp.getString("url", "");
                    String apk = sp.getString("apk", "");
                    boolean start_install = sp.getBoolean("start_install", false);
                    sp.edit().remove("url").commit();
                    sp.edit().remove("info").commit();
                    sp.edit().remove("apk").commit();
                    sp.edit().remove("start_install").commit();

                    if (start_install) {
                        long currentVersion = Android.getVersionCode(mContext, mContext.getPackageName());
                        LogUtils.SubmitLog log = new LogUtils.SubmitLog(LogUtils.PRODUCTID_HALL, "onUpgradeInstallEnd");
                        log.addParam("apk", apk);
                        log.addParam("currentVersion", Android.getVersionName(mContext, mContext.getPackageName()));
                        log.addParam("targetVersion", __info.versionName);
                        log.addParam("url", _url);
                        if (currentVersion == __info.versionCode) {
                            log.addParam("result", "success");
                            LogUtils.d("HallUpgradeKernel", "onUpgradeInstallEnd success!!!");

                        } else {
                            log.addParam("result", "fail");
                            LogUtils.d("HallUpgradeKernel", "onUpgradeInstallEnd fail!!!");
                        }
                        LogUtils.submit(log);
                    }
                }
            } else {
                LogUtils.d("HallUpgradeKernel", Android.getVersionName(mContext, mContext.getPackageName()) + " is NOT first start!!!");
                UpgradeInfo __info = null;
                try {
                    String _info = sp.getString("info", "");
                    __info = UpgradeInfo.parseJObject(_info, UpgradeInfo.class);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                if (__info != null) {
                    String _url = sp.getString("url", "");
                    String apk = sp.getString("apk", "");
                    boolean start_install = sp.getBoolean("start_install", false);
                    sp.edit().remove("url").commit();
                    sp.edit().remove("info").commit();
                    sp.edit().remove("apk").commit();
                    sp.edit().remove("start_install").commit();
                    if (start_install) {
                        String currentVersion = Android.getVersionName(mContext, mContext.getPackageName());
                        LogUtils.SubmitLog log = new LogUtils.SubmitLog(LogUtils.PRODUCTID_HALL, "onUpgradeInstallEnd");
                        log.addParam("apk", apk);
                        log.addParam("currentVersion", currentVersion);
                        log.addParam("targetVersion", __info.versionName);
                        log.addParam("url", _url);
                        log.addParam("result", "fail");
                        LogUtils.submit(log);
                        LogUtils.d("HallUpgradeKernel", "onUpgradeInstallEnd fail!!!");
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void _getUpgradeInfo(String device_channel) {
        LogUtils.e("upgrade", "_getUpgradeInfo  device_channel:" + device_channel);
        StoreApkInfo apkinfo = null;
        try {
            apkinfo = CoocaaApplication.getCoocaaWebService().getAppStoreService()
                    .updateGeneralPlat(device_channel);
            if (apkinfo != null) {
                String j = JSONObject.toJSONString(apkinfo);
                LogUtils.i("upgrade", "apkinfo:" + j);
                info.versionCode = Integer.valueOf(apkinfo.verCode);
                try {
                    LogUtils.i("upgrade", "web info.versionCode:" + info.versionCode + " app verCode:" + mContext.getPackageManager().getPackageInfo(mContext.getPackageName(), 0).versionCode);
                    if (info.versionCode > mContext.getPackageManager().getPackageInfo(mContext.getPackageName(), 0).versionCode) {
                        info.hasUpgrade = true;
                        info.versionName = apkinfo.verName;
                        info.name = apkinfo.appName;
                        info.size = 0;
                        info.upgradeLog = apkinfo.updateInfo;
                        info.md5 = apkinfo.md5;
                        url = apkinfo.apkDownUrl;

                        sp.edit().putString("info", info.toJSONString()).commit();
                        sp.edit().putString("url", url).commit();
                    } else {
                        info.hasUpgrade = false;
                        url = "";
                    }
                } catch (PackageManager.NameNotFoundException e) {
                    info.hasUpgrade = false;
                    url = "";
                }
            } else {
                info.hasUpgrade = false;
                url = "";
            }
        } catch (Exception e) {
            e.printStackTrace();
            LogAPIForAppStore.reportInterfaceError("获取商城APK信息", Android.throwable2String(e));
            info.hasUpgrade = false;
            url = "";
        }

//        test();
    }

    private void test() {
        info.hasUpgrade = true;
        info.versionCode = 81;
        info.versionName = "2.3";
        info.name = "测试升级app";
        info.size = 0;
        info.upgradeLog = "測試升級app日誌:\n1、zcvzxczxczxczczx3123123\n2、支持v131312312字吃頓飯犬瘟熱1 12全文啊";
        url = "http://stockapp.finance.qq.com/apk/QQStock_Android_4.0.1_18.apk";
    }

    @Override
    public void prepare(final UpgradeParams params) {

        String value = params.params.get("show_dialog");
        if (value == null || !value.equals("only_has_update"))
            show_dialog_type = SHOW_DIALOG_TYPE_ALL;
        else
            show_dialog_type = SHOW_DIALOG_TYPE_ONLY_HAS_UPDATE;
        LogUtils.i("upgrade", "show_dialog_type:" + show_dialog_type + " value:" + value);

        LiteHandlerThread.postOnUiThread(new Runnable() {
            @Override
            public void run() {
                if (upgradeDialog == null) {
                    upgradeDialog = new UpgradeDialog(mContext);
                    upgradeDialog.setOnUpdateEventListener(new UpgradeDialog.OnUpgradeDialogEventListener() {
                        @Override
                        public void onClickCallBack(String apkFilePath) {
                            if (apkFilePath != null && apkFilePath.length() > 0) {
                                CoocaaApplication.CoocaaVersion cv = null;
                                try {
                                    try {
                                        Runtime.getRuntime().exec("chmod -R 755 " + apkFilePath);
                                    } catch (Exception e) {
                                        e.printStackTrace();
                                    }

                                    File f = new File(apkFilePath);
                                    try {
                                        if (f.exists()) {
                                            LogUtils.d("upgrade", " set file r w e  ");
                                            f.setReadable(true, false);
                                            f.setWritable(true, false);
                                            f.setExecutable(true, false);
                                        }
                                    } catch (Exception e1) {
                                        LogUtils.d("upgrade", " set  error!!!!!!!!!");
                                        e1.printStackTrace();
                                    }
                                    cv = CoocaaApplication.getCoocaaVersion();
                                    if (cv.major >= 5)
                                        installWithAutoInstaller(apkFilePath);
                                    else
                                        installWithPackageInstaller(apkFilePath);
                                } catch (Exception e) {
                                    installWithPackageInstaller(apkFilePath);
                                }
                                LogUtils.SubmitLog log = new LogUtils.SubmitLog(LogUtils.PRODUCTID_HALL, "onUpgradeInstallStart");
                                log.addParam("apk", apkFilePath);
                                log.addParam("currentVersion", Android.getVersionName(mContext, mContext.getPackageName()));
                                log.addParam("targetVersion", info.versionName);
                                log.addParam("url", url);
                                LogUtils.submit(log);
                                LogUtils.d("HallUpgradeKernel", "onUpgradeInstallStart!!!");
                                sp.edit().putString("apk", apkFilePath).commit();
                                sp.edit().putBoolean("start_install", true).commit();
                            }
                        }
                    });
                }
                boolean can_show_loading = Boolean.valueOf(params.params.get("can_show_loading"));
                if (can_show_dialog && can_show_loading)
                    upgradeDialog.show();
            }
        });

        String device_channel = params.params.get("device_channel");
        _getUpgradeInfo(device_channel);
    }

    @Override
    public String exec(String cmd, UpgradeParams params) {
        LogUtils.i("upgrade", "cmd:" + cmd);
        if (cmd.equals("enable_dialog"))
            can_show_dialog = true;
        else if (cmd.equals("disable_dialog"))
            can_show_dialog = false;
        return "";
    }

    @Override
    public String getDownloadUrl() {
        return url;
    }

    @Override
    public UpgradeInfo getUpgradeInfo() {
        return info;
    }

    @Override
    public void onStart() {
        super.onStart();
        LogUtils.SubmitLog log = new LogUtils.SubmitLog(LogUtils.PRODUCTID_HALL, "onUpgradeDownloadStart");
        log.addParam("currentVersion", Android.getVersionName(mContext, mContext.getPackageName()));
        log.addParam("targetVersion", info.versionName);
        log.addParam("url", url);
        LogUtils.submit(log);
        LogUtils.d("HallUpgradeKernel", "onUpgradeDownloadStart!!!");
    }

    @Override
    public void onProgress(int percent, long downloaded_length, long file_length) {
        super.onProgress(percent, downloaded_length, file_length);
    }

    @Override
    public void onError(String e) {
        super.onError(e);
        LogUtils.SubmitLog log = new LogUtils.SubmitLog(LogUtils.PRODUCTID_HALL, "onUpgradeDownloadEnd");
        log.addParam("result", "fail");
        log.addParam("currentVersion", Android.getVersionName(mContext, mContext.getPackageName()));
        log.addParam("targetVersion", info.versionName);
        log.addParam("url", url);
        log.addParam("failmsg", e);
        LogUtils.submit(log);
        LogUtils.d("HallUpgradeKernel", "onUpgradeDownloadEnd fail!!!" + e);
    }

    @Override
    public void onSuccess(File f) {
        super.onSuccess(f);
        LogUtils.SubmitLog log = new LogUtils.SubmitLog(LogUtils.PRODUCTID_HALL, "onUpgradeDownloadEnd");
        log.addParam("result", "success");
        log.addParam("currentVersion", Android.getVersionName(mContext, mContext.getPackageName()));
        log.addParam("targetVersion", info.versionName);
        log.addParam("url", url);
        LogUtils.submit(log);
        LogUtils.d("HallUpgradeKernel", "onUpgradeDownloadEnd success!!!");
    }

    @Override
    public void onCancel() {
        super.onCancel();
    }

    @Override
    public void onUpdateFilePrepared(final String path) {
        super.onUpdateFilePrepared(path);
        LiteHandlerThread.postOnUiThread(new Runnable() {
            @Override
            public void run() {

                if (can_show_dialog) {
                    upgradeDialog.show();
                    upgradeDialog.refreshUpdateMsg(info.upgradeLog, path);
                }
            }
        });
    }

    @Override
    public void onUpdateFileNotExist() {
        super.onUpdateFileNotExist();
        LiteHandlerThread.postOnUiThread(new Runnable() {
                                             @Override
                                             public void run() {
                                                 if (can_show_dialog && show_dialog_type == SHOW_DIALOG_TYPE_ALL) {
                                                     upgradeDialog.show();
                                                     upgradeDialog.refreshUpdateMsg(mContext.getResources().getString(R.string.upgrade_no_upgradeinfo), "");
                                                 }
                                             }
                                         }

        );
    }

    private int getApkPreferInstallLocation(String file) {
        int installlocation = 0;
        try {
            PackageParser.PackageLite pkg = null;
            if (Build.VERSION.SDK_INT < 21) {
                Method staticMethod = PackageParser.class.getDeclaredMethod("parsePackageLite",
                        new Class[]{String.class, int.class});
                pkg = (PackageParser.PackageLite) staticMethod.invoke(null, new Object[]{
                        file, 0});
            } else {
                Method staticMethod = PackageParser.class.getDeclaredMethod("parsePackageLite",
                        new Class[]{File.class, int.class});
                pkg = (PackageParser.PackageLite) staticMethod.invoke(null, new Object[]{
                        new File(file), 0});
            }
            if (pkg != null)
                installlocation = pkg.installLocation;
            Runtime.getRuntime().gc();
        } catch (NoSuchMethodException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return installlocation;
    }

    private static final int INSTALL_LOCATION_UNSPECIFIED = -1;
    private static final int INSTALL_LOCATION_AUTO = 0;
    private static final int INSTALL_LOCATION_INTERNAL_ONLY = 1;
    private static final int INSTALL_LOCATION_PREFER_EXTERNAL = 2;

    private void installWithPackageInstaller(String apkfile) {
        try {
            Uri uri = Uri.fromFile(new File(apkfile));
            Intent intent = new Intent(Intent.ACTION_VIEW);
            intent.setDataAndType(uri, "application/vnd.android.package-archive");
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            intent.putExtra("SKYWORTH_HIDE_FLAG_PACKAGENAME", mContext.getPackageName());

            int preferlocation = getApkPreferInstallLocation(apkfile);
            LogUtils.d("HHHH", "preferlocation:" + preferlocation);
            switch (preferlocation) {
                case INSTALL_LOCATION_INTERNAL_ONLY:
                    intent.putExtra("APP_INSTALL_LOCATION", 1);
                    break;
                case INSTALL_LOCATION_PREFER_EXTERNAL:
                case INSTALL_LOCATION_AUTO:
                case INSTALL_LOCATION_UNSPECIFIED:
                    if (SdCardChecker.isSDCardAvaiable()) {
                        intent.putExtra("APP_INSTALL_LOCATION", 2);
                    } else {
                        intent.putExtra("APP_INSTALL_LOCATION", 0);
                    }
                    break;
            }
            mContext.startActivity(intent);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    private void installWithAutoInstaller(String apkfile) {
        try {
            Intent intent = new Intent("coocaa.intent.action.AUTOINSTALLER");
            intent.putExtra("apkfilepath", apkfile);
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            mContext.startActivity(intent);
        } catch (Exception e) {
            installWithPackageInstaller(apkfile);
        }
    }
}
